package com.luoxi.springboot.util;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

/**
 * mybatis-plus代码生成器
 *
 * @author 夏智峰
 * @create 2018-06-24 9:52
 */
public class MpGenerator {
  public static void main(String[] args) {
    AutoGenerator mpg = new AutoGenerator();
//    可以选择freemarker引擎，默认Veloctiy
    mpg.setTemplateEngine(new FreemarkerTemplateEngine());

    //全局配置
    setGlobalConfig(mpg);

    //数据源配置
    setDataSourceConfig(mpg);

    //策略配置
    setStrategyConfig(mpg);

    //包配置
    setPackageConfig(mpg);

    //注入自定义配置，可以在vm中使用cfg.abc【可无】
//    setCfg(mpg);

    //自定义模板
    setTemplateConfig(mpg);

    //执行生成
    mpg.execute();
  }


  //自定义模板
  private static void setTemplateConfig(AutoGenerator mpg) {
    TemplateConfig tc = new TemplateConfig();
    tc.setController(null);
    tc.setService(null);
    tc.setServiceImpl(null);
    tc.setMapper("/generator/model/mapper.java");
    tc.setEntity("/generator/model/entity.java");
    tc.setXml("/generator/model/mapper.xml");
    mpg.setTemplate(tc);

    // 自定义模板配置，可以 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改，
    // 放置自己项目的 src/main/resources/templates 目录下, 默认名称一下可以不配置，也可以自定义模板名称
    // TemplateConfig tc = new TemplateConfig();
    // tc.setController("...");
    // tc.setEntity("...");
    // tc.setMapper("...");
    // tc.setXml("...");
    // tc.setService("...");
    // tc.setServiceImpl("...");
    // 如上任何一个模块如果设置 空 OR Null 将不生成该模块。
    // mpg.setTemplate(tc);
  }

  //注入自定义配置，可以在vm中使用cfg.abc【可无】
//  private static void setCfg(AutoGenerator mpg) {
//    InjectionConfig cfg = new InjectionConfig() {
//      @Override
//      public void initMap() {
//        Map<String, Object> map = new HashMap<>();
//        map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
//        this.setMap(map);
//      }
//    };
//
//    List<FileOutConfig> focList = new ArrayList<>();
//
//    //调整model生成目录
//    focList.add(new FileOutConfig("/generator/model/entity.java.ftl") {
//      @Override
//      public String outputFile(TableInfo tableInfo) {
//        return "/com/luoxi/springboot/entity/" + tableInfo.getEntityName() + ".java";
//      }
//    });
//
//    //调整mapper生成目录
//    focList.add(new FileOutConfig("/generator/model/mapper.java.ftl") {
//      @Override
//      public String outputFile(TableInfo tableInfo) {
//        return "/com/luoxi/springboot/mapper/" + tableInfo.getMapperName() + ".java";
//      }
//    });
//    cfg.setFileOutConfigList(focList);
//    mpg.setCfg(cfg);
//  }

  //包配置
  private static void setPackageConfig(AutoGenerator mpg) {
    PackageConfig pc = new PackageConfig();
    pc.setParent("com.luoxi");
    pc.setModuleName("springboot");
    mpg.setPackageInfo(pc);
  }

  //全局配置
  private static void setGlobalConfig(AutoGenerator mpg) {
    //全局配置
    GlobalConfig gc = new GlobalConfig();
    gc.setOutputDir("D://generator");
    gc.setFileOverride(true);
    gc.setActiveRecord(false); //不需要ActiveRecord特性，可以改为false
    gc.setEnableCache(false); //xml二级缓存
    gc.setBaseResultMap(true); //xml ResultMap
    gc.setBaseColumnList(true); //xml columList
    gc.setKotlin(false); //是否生成kotlin代码
    gc.setAuthor("夏智峰");

    //自定义文件命名，%s会自动填充表实体属性
    gc.setMapperName("%sMapper");
    gc.setXmlName("%sMapper");
    gc.setServiceName("%sService");
    gc.setServiceImplName("%sServiceImpl");
    gc.setControllerName("%sAction");

    mpg.setGlobalConfig(gc);
  }

  //数据源配置
  private static void setDataSourceConfig(AutoGenerator mpg) {
    DataSourceConfig dsc = new DataSourceConfig();
    dsc.setDbType(DbType.MYSQL);
    dsc.setTypeConvert(new MySqlTypeConvert() {
      //自定义数据库表字段类型转换【可选】

      @Override
      public DbColumnType processTypeConvert(String fieldType) {
        System.out.println("转换类型：" + fieldType);
        //将int转Long类型
        if (fieldType.equals("int")) {
          return DbColumnType.LONG;
        }
        return super.processTypeConvert(fieldType);
      }
    });
    dsc.setDriverName("com.mysql.jdbc.Driver");
    dsc.setUsername("root");
    dsc.setPassword("root");
    dsc.setUrl("jdbc:mysql://127.0.0.1:3306/meijiaosuo?characterEncoding=utf8");

    mpg.setDataSource(dsc);
  }

  //策略配置
  private static void setStrategyConfig(AutoGenerator mpg) {

    StrategyConfig sc = new StrategyConfig();
//    sc.setCapitalMode(true);//全局大写命名ORACLE注意
//    sc.setTablePrefix(new String[]{"tlog_", "tsys_"});// 此处可以修改为要要生成的表前缀
    sc.setNaming(NamingStrategy.underline_to_camel);//表名生产策略,驼峰命名

    //如果下边这两个都不写则默认生成该库的所有表
//    sc.setInclude(new String[]{"user"});//需要生成的表
//    sc.setExclude(new String[]{"user"});//排除生成的表

    // 自定义实体父类
    // strategy.setSuperEntityClass("com.baomidou.demo.TestEntity");
    // 自定义实体，公共字段
    // strategy.setSuperEntityColumns(new String[] { "test_id", "age" });
    // 自定义 mapper 父类
    // strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");
    // 自定义 service 父类
    // strategy.setSuperServiceClass("com.baomidou.demo.TestService");
    // 自定义 service 实现类父类
    // strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl");
    // 自定义 controller 父类
    // strategy.setSuperControllerClass("com.baomidou.demo.TestController");
    // 【实体】是否生成字段常量（默认 false）
    // public static final String ID = "test_id";
    // strategy.setEntityColumnConstant(true);
    // 【实体】是否为构建者模型（默认 false）
    // public User setName(String name) {this.name = name; return this;}
    // strategy.setEntityBuilderModel(true);

    mpg.setStrategy(sc);
  }

}
